package cc.rengu.igas.channel.uprk.core.service.trans;

import cc.rengu.igas.channel.uprk.common.constant.UprkParamConstant;
import cc.rengu.igas.channel.uprk.common.constant.UprkServiceConstant;
import cc.rengu.igas.channel.uprk.common.constant.UprkTreeNodeConstant;
import cc.rengu.igas.channel.uprk.common.enums.BankCardRiskEnum;
import cc.rengu.igas.channel.uprk.common.enums.RespCodeEnum;
import cc.rengu.igas.channel.uprk.common.utils.UprkSecurityUtil;
import cc.rengu.igas.channel.uprk.core.model.ChnlBizResponse;
import cc.rengu.igas.channel.uprk.core.service.base.QueryService;
import cc.rengu.igas.channel.uprk.facade.request.BankCardShareMchntVerifyRequest;
import cc.rengu.igas.channel.uprk.facade.response.BankCardShareMchntVerifyResponse;
import cc.rengu.jradp.schedule.Schedule;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.KeyInfoMapper;
import cc.rengu.oltp.service.common.dao.SecPlanInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.KeyInfoMapperImpl;
import cc.rengu.oltp.service.common.dao.impl.SecPlanInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.*;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.communication.HttpMethod;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @version 1.0.0
 * @date 2021/4/27 14:00
 */
public class BankCardShareMchntVerifyService extends QueryService {
    @Override
    protected Object beforeBizProcess() throws Exception {
        BankCardShareMchntVerifyRequest bankCardShareMchntVerifyRequest = new BankCardShareMchntVerifyRequest();
        ConvertUtil.convertOutput(bankCardShareMchntVerifyRequest);
        return bankCardShareMchntVerifyRequest;
    }

    @Override
    protected ChnlBizResponse callBizService(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        BankCardShareMchntVerifyRequest bankCardShareMchntVerifyRequest = (BankCardShareMchntVerifyRequest) request;
        BankCardShareMchntVerifyResponse bankCardSharePersonalVerifyResponse = new BankCardShareMchntVerifyResponse();
        DstChannelCfg dstChannelCfg = (DstChannelCfg) xmlTreeUtil.getXmlTreeObjectValue(UprkTreeNodeConstant.DST_CHANNEL_CFG, DstChannelCfg.class);
        DstChannelInfo dstChannelInfo = (DstChannelInfo) xmlTreeUtil.getXmlTreeObjectValue(UprkTreeNodeConstant.DST_CHANNEL_INFO, DstChannelInfo.class);

        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam;
        String token = null;
        String instId = bankCardShareMchntVerifyRequest.getHeader().getInstId();
        xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.INST_ID, instId);
        if (StringUtil.isEmptyOrNull(bankCardShareMchntVerifyRequest.getAppid())) {
            /*//通过机构号从系统参数表获取appid
            sysParam = sysParamService.getSysParamInfo(instId,"UNIONOPENPLATPARAM","app_id");
            if(null == sysParam){
                rglog.error("该行未配置银行卡风险信息共享查询参数app_id，请配置后进行处理!");
                throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(),RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
            }*/
            bankCardShareMchntVerifyRequest.setAppid(dstChannelCfg.getAppId());
        }
        //获取token
        token = RedisUtil.onceGet(UprkParamConstant.UPRK_BANK_CARD_TOKEN_CACHE_NAME + bankCardShareMchntVerifyRequest.getAppid());
        if (null == token) {
            //重新获取token
            //判断appSecret是否上送
            if (StringUtil.isEmptyOrNull(bankCardShareMchntVerifyRequest.getAppSecret())) {
                /*sysParam = sysParamService.getSysParamInfo(instId,"UNIONOPENPLATPARAM","app_secret");
                if(null == sysParam){
                    rglog.error("该行未配置银行卡风险信息共享查询参数app_secret，请配置后进行处理!");
                    throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(),RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
                }*/
                String appSecret = getAppSecret(dstChannelCfg);
                if (null == appSecret) {
                    rglog.error("该行未配置银行卡风险信息共享查询参数app_secret，请配置后进行处理!");
                    throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
                }
                bankCardShareMchntVerifyRequest.setAppSecret(appSecret);
            }
            token = getUprkProdToken(bankCardShareMchntVerifyRequest.getAppid(), bankCardShareMchntVerifyRequest.getAppSecret());
        }
        //设置body,ts,signature
        //获取signature
        /*sysParam = sysParamService.getSysParamInfo(instId ,"UNIONOPENPLATPARAM","signature");
        if(null == sysParam){
            rglog.error("该行未配置银行卡风险信息共享查询参数signature，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(),RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }*/
        String signature = getSignature(dstChannelCfg);
        if (null == signature) {
            rglog.error("该行未配置银行卡风险信息共享查询参数signature，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }
        //获取机构码
        sysParam = sysParamService.getSysParamInfo(instId, "UNIONOPENPLATPARAM", "orgCode");
        if (null == sysParam) {
            rglog.error("该行未配置银行卡风险信息共享查询参数signature，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }
        String insIdCd = sysParam.getParamValue();
        xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.INS_ID_CD, insIdCd);

        //获取用户代码
        sysParam = sysParamService.getSysParamInfo(instId, "UNIONOPENPLATPARAM", "userCode");
        if (null == sysParam) {
            rglog.error("该行未配置银行卡风险信息共享查询参数signature，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }
        String usrId = sysParam.getParamValue();
        xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DATA_USR_ID, usrId);
        xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DATA_QUERY_TP, bankCardShareMchntVerifyRequest.getQueryType());
        Map<String, String> reqMap = new HashMap<>();
        reqMap.put("usrId", usrId);
        reqMap.put("queryTp", bankCardShareMchntVerifyRequest.getQueryType());

        if (!StringUtil.isEmptyOrNull(bankCardShareMchntVerifyRequest.getMchntNo())) {
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DATA_MCHNT_CD, bankCardShareMchntVerifyRequest.getMchntNo());
            reqMap.put("mchntCd", bankCardShareMchntVerifyRequest.getMchntNo());
        }
        if (!StringUtil.isEmptyOrNull(bankCardShareMchntVerifyRequest.getMchntName())) {
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DATA_MCHNT_NM, bankCardShareMchntVerifyRequest.getMchntName());
            reqMap.put("mchntNm", bankCardShareMchntVerifyRequest.getMchntName());
        }
        if (!StringUtil.isEmptyOrNull(bankCardShareMchntVerifyRequest.getUnifiedSocialCreditCode())) {
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DATA_UNIFIED_SOCIAL_CREDIT_CODE, bankCardShareMchntVerifyRequest.getUnifiedSocialCreditCode());
            reqMap.put("unifiedSocialCreditCode", bankCardShareMchntVerifyRequest.getUnifiedSocialCreditCode());
        }
        if (!StringUtil.isEmptyOrNull(bankCardShareMchntVerifyRequest.getLegalPersonIdCardNo())) {
            String legalPersonIDCardNo = new String(SM3Util.digest(bankCardShareMchntVerifyRequest.getLegalPersonIdCardNo().getBytes()));
            xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DATA_LEGAL_PERSON_CERTIF_ID, legalPersonIDCardNo);
            reqMap.put("legalPersonCertifId", legalPersonIDCardNo);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("insIdCd", insIdCd);
        jsonObject.put("data", reqMap);
        long ts = DateUtil.getCurrentTimeStamp();
        xmlTreeUtil.setXmlTreeLongValue("ts", ts);
        String sign = UprkSecurityUtil.encodeBySHA256(signature + jsonObject.toJSONString() + ts);

        sysParam = sysParamService.getSysParamInfo(instId, "UPRKBANKCARDSHAREQUERY", "mchntvfy");
        if (null == sysParam) {
            rglog.error("该行未配置银行卡风险信息共享查询参数personalvfy-requestUrl，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }
        String requestUrl = sysParam.getParamValue();
        requestUrl = requestUrl.replace("[token]", token).replace("[sign]", sign).replace("[ts]", String.valueOf(ts));
        xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE, requestUrl);
        Schedule schedule = new Schedule();
        int iReturnCode = schedule.callService(UprkServiceConstant.UPRK_BANK_CARD_SHARE_CLIENT_SERVICE, HttpMethod.POST);
        if (xmlTreeUtil.isExist(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE)) {
            xmlTreeUtil.deleteXmlTreeNode(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE);
        }
        if (0 != iReturnCode) {
            //通讯失败
            throw new BizException(RespCodeEnum.REQUEST_UPRK_ERROR.getRespCode(), RespCodeEnum.REQUEST_UPRK_ERROR.getRespDesc());
        }
        //通讯成功
        String respCd = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD);
        if (UprkParamConstant.BANK_CARD_SHARE_SUCCESS.equals(respCd)) {
            //个人风险信息查询成功
            bankCardSharePersonalVerifyResponse.setRespCode(OltpRpcdEnum.TRANS_SUCCESS.getRespCode());
            bankCardSharePersonalVerifyResponse.setRespDesc(OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            bankCardSharePersonalVerifyResponse.setRespMsg(OltpRpcdEnum.TRANS_SUCCESS.getRespDesc());
            String hitFlag = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.HIT_IN);
            if ("1".equals(hitFlag)) {
                bankCardSharePersonalVerifyResponse.setHitFlag(AppParamConstant.YES);
                //处理命中风险数据
                String hitRiskType = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.HIT_IN_RISK_TP);
                bankCardSharePersonalVerifyResponse.setHitRiskType(hitRiskType);
                String[] hitRiskTypeArr = hitRiskType.split(",");
                StringBuilder hitRiskDesc = new StringBuilder();
                for (int i = 0; i < hitRiskTypeArr.length; i++) {
                    hitRiskDesc.append(BankCardRiskEnum.getEnumValue(hitRiskTypeArr[i])).append(",");
                }
                bankCardSharePersonalVerifyResponse.setHitRiskDesc(hitRiskDesc.substring(0, hitRiskDesc.length() - 1));
                String hitInfoVfy = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.HIT_IN_VFY);
                bankCardSharePersonalVerifyResponse.setHitInfoVfy(hitInfoVfy);
                String hitInfoRiskActType = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.HIT_IN_RISK_ACT_TP);
                bankCardSharePersonalVerifyResponse.setHitInfoRiskActType(hitInfoRiskActType);
                String reportTime = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RPT_TM);
                bankCardSharePersonalVerifyResponse.setReportTime(reportTime);
            } else {
                bankCardSharePersonalVerifyResponse.setHitFlag(AppParamConstant.NO);
            }
        } else {
            //个人风险信息查询失败
            rglog.error("个人风险信息查询失败！");
            throw new BizException(StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD)) ? RespCodeEnum.PERSONAL_VERIFY_ERROR.getRespCode() : xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD),
                    StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_MSG)) ? RespCodeEnum.PERSONAL_VERIFY_ERROR.getRespDesc() : xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_MSG));
        }

        ChnlBizResponse chnlBizResponse = new ChnlBizResponse();
        chnlBizResponse.setResult(bankCardSharePersonalVerifyResponse);
        rglog.debug("bankCardSharePersonalVerifyResponse = <{}>", JSONObject.toJSONString(chnlBizResponse));
        return chnlBizResponse;
    }

    @Override
    protected void afterBizProcess(ChnlBizResponse response) throws Exception {
        BankCardShareMchntVerifyResponse bankCardSharePersonalVerifyResponse = (BankCardShareMchntVerifyResponse) response.getResult();
        ConvertUtil.convertInput(bankCardSharePersonalVerifyResponse);
    }

    private String getUprkProdToken(String appid, String appSecret) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, "UPRKBANKCARDSHAREQUERY", "gettoken");
        if (null == sysParam) {
            rglog.error("该行未配置银行卡风险信息共享查询参数gettoken-requestUrl，请配置后进行处理!");
            throw new BizException(RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespCode(), RespCodeEnum.GET_BANK_CARD_SHARE_PARAM_ERROR.getRespDesc());
        }
        String requestUrl = sysParam.getParamValue();
        requestUrl = requestUrl.replace("[app_id]", appid).replace("[app_secret]", appSecret);
        xmlTreeUtil.setXmlTreeStringValue(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE, requestUrl);
        Schedule schedule = new Schedule();
        int iReturnCode = schedule.callService(UprkServiceConstant.UPRK_BANK_CARD_SHARE_CLIENT_SERVICE, HttpMethod.POST);
        if (xmlTreeUtil.isExist(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE)) {
            xmlTreeUtil.deleteXmlTreeNode(UprkTreeNodeConstant.DEFINE_HTTP_URL_NODE);
        }
        if (0 != iReturnCode) {
            //通讯失败
            throw new BizException(RespCodeEnum.REQUEST_UPRK_ERROR.getRespCode(), RespCodeEnum.REQUEST_UPRK_ERROR.getRespDesc());
        }
        //通讯成功
        String respCd = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD);
        String token;
        String expireIn;
        if (UprkParamConstant.BANK_CARD_SHARE_SUCCESS.equals(respCd)) {
            //获取TOKEN成功
            token = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.TOKEN);
            expireIn = xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.EXPIRE_IN);
            /*加载到redis缓存*/
            RedisUtil.onceSet(UprkParamConstant.UPRK_BANK_CARD_TOKEN_CACHE_NAME + xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.APP_ID), token, StringUtil.isEmptyOrNull(expireIn) ? UprkParamConstant.TOKEN_DEFAULT_EXPIRY_TIME : Integer.parseInt(expireIn));
        } else {
            //获取TOKEN失败
            rglog.error("获取银行卡风险信息查询产品TOKEN失败！");
            throw new BizException(StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD)) ? RespCodeEnum.GET_PROD_TOKEN_ERROR.getRespCode() : xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_CD),
                    StringUtil.isEmptyOrNull(xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_MSG)) ? RespCodeEnum.GET_PROD_TOKEN_ERROR.getRespDesc() : xmlTreeUtil.getXmlTreeStringValue(UprkTreeNodeConstant.RESP_MSG));
        }
        return token;
    }

    private String getAppSecret(DstChannelCfg dstChannelCfg) throws Exception {
        /* 根据通道安全计划获取安全计划 */
        SecPlanInfoMapper secPlanInfoMapper = new SecPlanInfoMapperImpl();
        List<SecPlanInfo> secPlanInfoList = secPlanInfoMapper.selectSecPlanInfoBySecPlanId(dstChannelCfg.getInstId(), dstChannelCfg.getSecPlanId());
        if (null != secPlanInfoList && !secPlanInfoList.isEmpty()) {
            Optional<SecPlanInfo> secPlanInfoOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(UprkParamConstant.SECRET_KEY_TYPE)).findFirst();
            if (secPlanInfoOpt.isPresent()) {
                KeyInfoMapper keyInfoMapper = new KeyInfoMapperImpl();
                KeyInfo keyInfo = keyInfoMapper.selectKeyInfoByPrimaryKey(dstChannelCfg.getInstId() + secPlanInfoOpt.get().getSecPlanId() + secPlanInfoOpt.get().getSecPlanType());
                if (keyInfo != null) {
                    return keyInfo.getKeyValue();
                }
            }
        }
        return null;
    }

    private String getSignature(DstChannelCfg dstChannelCfg) throws Exception {
        /* 根据通道安全计划获取安全计划 */
        SecPlanInfoMapper secPlanInfoMapper = new SecPlanInfoMapperImpl();
        List<SecPlanInfo> secPlanInfoList = secPlanInfoMapper.selectSecPlanInfoBySecPlanId(dstChannelCfg.getInstId(), dstChannelCfg.getSecPlanId());
        if (null != secPlanInfoList && !secPlanInfoList.isEmpty()) {
            Optional<SecPlanInfo> secPlanInfoOpt = secPlanInfoList.stream().filter(item -> item.getSecPlanType().equals(UprkParamConstant.SIGNATURE_TYPE)).findFirst();
            if (secPlanInfoOpt.isPresent()) {
                KeyInfoMapper keyInfoMapper = new KeyInfoMapperImpl();
                KeyInfo keyInfo = keyInfoMapper.selectKeyInfoByPrimaryKey(dstChannelCfg.getInstId() + secPlanInfoOpt.get().getSecPlanId() + secPlanInfoOpt.get().getSecPlanType());
                if (keyInfo != null) {
                    return keyInfo.getKeyValue();
                }
            }
        }
        return null;
    }
}
